#ifndef SHIJU_EM_PROCEDURE_CTRL_H_INCLUDE
#define SHIJU_EM_PROCEDURE_CTRL_H_INCLUDE

#include <string>
#include <list>
#include "BbuManager.h"
#include "TlvMessage.h"
#include "MessageDef.h"

class EmBaseProcedure;

class ProcedureCtrl
{
public:
    enum RCode
    {
        RC_PROC_CONTINUE,
        RC_PROC_END
    };
    ProcedureCtrl(std::string name);

    bool start();
    bool stop();
    ProcedureCtrl& addProcedure(EmBaseProcedure*);
    void processMessage(TlvMessage&, BbuCtrl&);

private:
    ProcedureCtrl(const ProcedureCtrl&);
    ProcedureCtrl& operator=(const ProcedureCtrl&);

    std::string name_;
    std::list<EmBaseProcedure*>::iterator currentProcIndex_;    
    std::list<EmBaseProcedure*> procedures_;
};


class EmBaseProcedure
{
public:
    EmBaseProcedure(std::string name);
    virtual ~EmBaseProcedure();
    std::string procName_;

    virtual bool start() = 0;
    virtual bool finish() = 0;
    virtual bool processMessage(TlvMessage&, BbuCtrl&) = 0;

    void saveProcedureCtrl(ProcedureCtrl*);
    std::string getName();

protected:
    ProcedureCtrl* procCtrlPtr_;
     
    bool registerMsgHandler(TlvMessage::Protocol_t, TlvMessage::Signal_t);
};

class CellConfigProcedure : public EmBaseProcedure
{
public:
    CellConfigProcedure();
    virtual ~CellConfigProcedure();

    virtual bool start();
    virtual bool finish();
    virtual bool processMessage(TlvMessage&, BbuCtrl&);

    BbuCtrl* bbu_;
    NmmToX86Protocol_CellConfig configMsg_;
private:
    CellConfigProcedure(const CellConfigProcedure&);
    CellConfigProcedure& operator=(const CellConfigProcedure&);
};

class StateReportProcedure : public EmBaseProcedure
{
public:
    virtual ~StateReportProcedure();
    virtual bool start();
    virtual bool finish();
    virtual bool processMessage(TlvMessage&, BbuCtrl&);
    void reportState(BbuCtrl&, BbuStateCode stateCode);

    static StateReportProcedure* instance();

    bool isTrgByOam_;
    StateReportProcedure* setBbu(BbuCtrl*);
private:
    StateReportProcedure();
    StateReportProcedure(const StateReportProcedure&);
    StateReportProcedure& operator=(const StateReportProcedure&);

    BbuCtrl* bbu_;
};

#define StateReportProcedurePtr (StateReportProcedure::instance())

#endif
